package com.getan.boot.module.system.controller;

import com.getan.boot.common.Pagination;
import com.getan.boot.common.ResponseBuilder;
import com.getan.boot.common.ResponseCodeData;
import com.getan.boot.common.annotation.OperateLog;
import com.getan.boot.common.domain.bo.IdBO;
import com.getan.boot.common.domain.bo.IdsBO;
import com.getan.boot.common.enums.EnableStatus;
import com.getan.boot.jdbc.customquery.CustomQueryBO;
import com.getan.boot.module.system.domain.bo.RoleBO;
import com.getan.boot.module.system.entity.RoleEntity;
import com.getan.boot.module.system.service.persistent.RoleService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.Valid;
import java.util.List;
import java.util.Set;

/**
 * 角色管理
 *
 * @author Bruce.Gong
 * @since 1.0.0-SNAPSHOT
 */
@Slf4j
@RequiredArgsConstructor
@RestController
@RequestMapping("/system/role")
public class RoleController {

    private final String MODULE = "角色管理";
    private final RoleService roleService;

    @PostMapping("search")
    public ResponseCodeData<Pagination<RoleEntity>> search(@RequestBody CustomQueryBO bo) {
        return ResponseBuilder.ok(roleService.page(bo));
    }

    @OperateLog(module = MODULE, businessType = "ADD")
    @PostMapping("add")
    public ResponseCodeData<Long> add(@RequestBody @Valid RoleBO.AddBO bo) {
        RoleEntity entity = new RoleEntity();
        BeanUtils.copyProperties(bo, entity);
        roleService.checkCode(entity);
        entity.setStatus(EnableStatus.ENABLE.getCode());
        roleService.insert(entity);
        roleService.removeCache();
        return ResponseBuilder.ok(entity.getId());
    }

    @OperateLog(module = MODULE, businessType = "UPDATE")
    @PostMapping("update")
    public ResponseCodeData<Long> update(@RequestBody @Valid RoleBO.UpdateBO bo) {
        RoleEntity entity = new RoleEntity();
        BeanUtils.copyProperties(bo, entity);
        roleService.canUpdate(bo.getId());
        roleService.update(entity);
        roleService.removeCache();
        return ResponseBuilder.ok(entity.getId());
    }

    @OperateLog(module = MODULE, businessType = "DELETE")
    @PostMapping("delete")
    public ResponseCodeData<Void> delete(@RequestBody @Valid IdsBO bo) {
        roleService.canDelete(bo.getIds());
        roleService.deleteRole(bo.getIds());
        roleService.removeCache();
        return ResponseBuilder.ok();
    }

    @OperateLog(module = MODULE, businessType = "DISABLE")
    @PostMapping("disable")
    public ResponseCodeData<Void> disable(@RequestBody @Valid IdsBO bo) {
        roleService.canDisable(bo.getIds());
        roleService.disable(bo.getIds());
        roleService.removeCache();
        return ResponseBuilder.ok();
    }

    @OperateLog(module = MODULE, businessType = "ENABLE")
    @PostMapping("enable")
    public ResponseCodeData<Void> enable(@RequestBody @Valid IdsBO bo) {
        roleService.canEnable(bo.getIds());
        roleService.enable(bo.getIds());
        roleService.removeCache();
        return ResponseBuilder.ok();
    }

    @OperateLog(module = MODULE, businessType = "ALLOC_USER")
    @PostMapping("alloc/user")
    public ResponseCodeData<Void> allocUser(@RequestBody @Valid RoleBO.AllocUserBO bo) {
        roleService.canUpdate(bo.getRoleId());
        roleService.allocUser(bo.getRoleId(), bo.getUserIds());
        return ResponseBuilder.ok();
    }

    @OperateLog(module = MODULE, businessType = "ALLOC_PERMISSION")
    @PostMapping("permissionIds")
    public ResponseCodeData<Set<Long>> permissionIds(@RequestBody @Valid IdBO bo) {
        return ResponseBuilder.ok(roleService.permissionIds(bo.getId()));
    }

    @OperateLog(module = MODULE, businessType = "ALLOC_PERMISSION")
    @PostMapping("alloc/permission")
    public ResponseCodeData<Void> allocPermission(@RequestBody @Valid RoleBO.AllocPermissionBO bo) {
        roleService.canUpdate(bo.getRoleId());
        roleService.allocPermission(bo.getRoleId(), bo.getPermissionIds());
        return ResponseBuilder.ok();
    }

    // region 通用查询方法

    @PostMapping("selector")
    public ResponseCodeData<List<RoleEntity>> selector() {
        return ResponseBuilder.ok(roleService.listActiveRoles());
    }

    // endregion

}
